package com.browsesoft.htmlcomponent;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import com.aote.model.DataShowTableModel;
import com.aote.util.StringHelper;
import com.browsesoft.ExtendElement;
import com.browsesoft.workflow.support.sortInterface;

/**
 * 不带翻页的表组件 表格带分类，表头不带分类，行不带分类
 * 
 * @author Browsesoft
 * @version 1.0
 */
public class HTMLTableComponent extends ReplacableParameterComponent {
	// 保存表头行元素
	protected Element tableHeadElement = null;

	// 请求
	protected HttpServletRequest request;

	// 保存表体行元素
	// protected Element tableLineElement = null;
	protected LinkedList rowType = new LinkedList();

	/**
	 * 构造器
	 * 
	 * @param parent
	 *            组件的父组件
	 * @throws Exception
	 */
	public HTMLTableComponent(HTMLBasicComponent parent) throws Exception {
		super(parent);
	}

	/**
	 * 初始化时
	 * 
	 * @param request
	 * @param e
	 * @throws Exception
	 */
	public void init(HttpServletRequest request, Element e) throws Exception {
		// 创建子组件并保存组件元素
		super.init(request, e);
		// 克隆element中的表头行元素
		Iterator iter = ExtendElement.findElements(element, "type", "head")
				.iterator();
		// 如果表头行元素不存在
		if (!iter.hasNext()) {
			// 出错
			throw new RuntimeException("缺少表头行元素，请在<tr>中加type='head'属性");
		}
		tableHeadElement = (Element) ((Element) iter.next()).cloneNode(true);
		// 克隆element中的表体行元素
		int trCount = ExtendElement.findElements(element, "type", "tr").size();
		// 对于每行
		for (int i = 0; i < trCount; i++) {
			// 克隆每行
			Element tableLineElement = (Element) ((Element) ExtendElement
					.findElements(element, "type", "tr").get(i))
					.cloneNode(true);
			rowType.add(tableLineElement);
		}
		// 修改表体行的check框列的onclick属性中resultdarpent的名字(要加上组件的名字)
		// 找有check框的元素(td元素)
		// 对于每行
		for (int i = 0; i < rowType.size(); i++) {
			Element tableLineElement = (Element) rowType.get(i);
			LinkedList list = ExtendElement.findElements(tableLineElement,
					"type", "check");
			// 如果有check框元素
			if (list.size() > 0) {
				Element tdElement = (Element) list.get(0);
				// 找到该元素中有choice="true"的元素
				Element ele = (Element) ExtendElement.findElements(tdElement,
						"choice", "true").get(0);
				// 找到该元素的onclick属性值
				String onclick = (String) ele.getAttribute("onclick");
				// 重新设置该属性值
				onclick = onclick.replaceAll("resultdarpent", "resultdarpent"
						+ "_" + this.name);
				// 替换onclick的属性值
				ele.setAttribute("onclick", onclick);
			}
		}
		this.createSearch();
		this.setComid();
	}

	/**
	 * 根据Model的内容更新需要处理的元素内容，在产生页面时要调用
	 * 
	 * @throws java.lang.Exception
	 */
	protected void updateElement() throws Exception {
		super.updateElement();
		this.element.setAttribute("id", this.name);
		// 找到element的表头行元素
		Element headLineElement = ((Element) ExtendElement.findElements(
				element, "type", "head").get(0));
		// 删除表头行元素的template子元素下的所有子结点
		ExtendElement.removeNodes(headLineElement, "template");
		// 构造表头
		createTableHead();
		// 删除element的tablebody元素的所有子结点
		ExtendElement.removeNodes(element, "tablebody");
		// 构造行元素
		createTableRows();
		// 修改Check框的名字
		NodeList list = this.element.getElementsByTagName("input");
		for (int i = 0; i < list.getLength(); i++) {
			Element e = (Element) list.item(i);
			if (e.hasAttribute("name")) {
				String name = (String) e.getAttribute("name");
				if (name.equals("resultdarpent")) {
					name = name.replaceAll(name, name + "_" + this.name);
					e.setAttribute("name", name);
				}
			}
		}
	}

	public void setComid() {
		LinkedList ls = ExtendElement.findElements(this.getElement(), "name",
				"selectall");
		if (ls.size() > 0) {
			Element e = (Element) ls.get(0);
			String onclick = e.getAttribute("onclick");
			onclick = onclick.replaceAll("comid", "resultdarpent_" + this.name);
			e.setAttribute("onclick", onclick);
		}
		ls = ExtendElement.findElements(this.getElement(), "name", "comid");
		if (ls.size() > 0) {
			Element e = (Element) ls.get(0);
			e.setAttribute("value", "resultdarpent_" + this.name);
		} else {
			ls = ExtendElement.findElements(this.getElement(), "name",
					"secondcomid");
			if (ls.size() > 0) {
				Element e = (Element) ls.get(0);
				e.setAttribute("value", "resultdarpent_" + this.name);
			}
		}
	}

	/**
	 * 构造表头
	 */
	protected void createTableHead() {
		// 读入表头
		Element tr = ((Element) ExtendElement.findElements(element, "type",
				"head").get(0));
		// 得到表头template结点
		Element template = (Element) tr.getElementsByTagName("template")
				.item(0);
		if (model != null) {
			for (int j = 0; j < ((HTMLTableModel) model).getColumnCount(); j++) {
				// 从tableHeadElement属性中得到列的类型，复制列
				Element tdElement = (Element) ExtendElement.findElements(
						tableHeadElement, "type", "td").get(0);
				// 添加新的表格元素
				Element td = (Element) tdElement.cloneNode(true);
				template.appendChild(td);
				// model是可排序
				if (this.model instanceof sortInterface) {
					try {
						String temp = ((HTMLTableModel) model).getColumnName(j);
						// 给该列加链接
						Element link = this.getPage().getDocument()
								.createElement("a");
						link.setAttribute("href", "page.jsp?" + this.name
								+ ".sort=" + this.model.getClass().getName()
								+ j + "&pagename=" + this.getPage().getName());
						link.setAttribute("class", "V_info_type");
						ExtendElement.replaceElementContext(td, link);
						Node text = this.getPage().getDocument()
								.createTextNode(temp);
						link.appendChild(text);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				// 用实际字段名称替换模板
				else {
					ExtendElement.replaceElementContext(td, this.getPage()
							.getDocument().createTextNode(
									((HTMLTableModel) model).getColumnName(j)));
				}
			}
		}
	}

	/**
	 * 构造行元素
	 * 
	 * @param start
	 *            起始行数
	 * @param end
	 *            结束行数
	 */
	protected void createTableRows(int start, int end) {
		// 如果model属于根据需要加载对象的类型
		if (model instanceof HTMLLazyTable) {
			// 让model加载对象
			HTMLLazyTable lazy = (HTMLLazyTable) model;
			lazy.loadData(start, end);
		}
		// 读入element的表体元素(tablebody)
		Element tablebody = (Element) element.getElementsByTagName("tablebody")
				.item(0);
		// 构造需要显示的行元素
		int count = ((HTMLTableModel) model).getRowCount();
		for (int i = start; i < end && i < count; i++) {
			// 行类型数
			int k = rowType.size();
			// 得到行的类型
			Element tableLineElement = (Element) ((Element) rowType.get(i % k))
					.cloneNode(true);
			// 复制行元素
			Element tr = (Element) tableLineElement.cloneNode(true);
			this.disposeSpecialTd(tr, i);
			// 清空template下的子结点
			ExtendElement.removeNodes(tr, "template");
			// 添加行元素到element行元素的父元素下
			tablebody.appendChild(tr);
			// 得到实现部分，并在实现部分插入表格
			// Element implement = (Element)
			// tr.getElementsByTagName("implement").item(0);
			for (int j = 0; j < ((HTMLTableModel) model).getColumnCount(); j++) {
				// 得到列的类型，复制列
				String colType = ((HTMLTableModel) model).getType(j);
				// 从tableLineElement属性中得到列类型
				Element tdElement = (Element) ExtendElement.findElements(
						tableLineElement, "type", colType).get(0);
				// 克隆新的表格元素
				Element td = (Element) tdElement.cloneNode(true);
				// 给tr的template元素增加列
				((Element) tr.getElementsByTagName("template").item(0))
						.appendChild(td);
				// 模型修改表格单元
				((HTMLTableModel) model).modifyCellValue(td, this.getPage()
						.getDocument(), i, j);
			}
		}
//		合并数据值一样的列
		if(ExtendElement.findElements(this.getElement(),"span", "span").iterator().hasNext()){
			this.SpanCol();
		}
	}
	/*
	 * 合并数据值一样的列
	 */
	private void SpanCol() {
		Element node = (Element) ExtendElement.findElements(this.getElement(),
				"span", "span").getFirst();
		Hashtable tempDatas = new Hashtable();
		int row = 0;
		int col = 0;
		// 获得页面数据
		for (row = 0; row < node.getElementsByTagName("datatemplate").getLength(); row++) {
			Element node_tr = (Element) node.getElementsByTagName("datatemplate").item(
					row);
			for (col = 0; col < 1; col++) {
				Node node_td = node_tr.getElementsByTagName("td").item(col);
				LinkedList lk = ExtendElement.findElementContext(node_td);
				// 获得页面的数据
				String content = "";
				if (lk.size() > 0
						&& !((Text) lk.get(0)).getNodeValue().trim().equals("")) {
					content = ((Text) lk.get(0)).getNodeValue().trim();
					System.out.print(content + "\t");
				}
				tempDatas.put(row + "_" + col, content);
			}
			System.out.println();
		}
		int[] base = new int[50];
		int v=0;
		if(node.hasAttribute("base")){
		// 获得第一列的合并项，以供其他列根据此列合并
			String aa="";String bb="";
			int dd = 1;
			int n=Integer.parseInt(node.getAttribute("base"));
			base[0]=0;
			for (int j = 0; j + 1 < row; j++) {
				aa = tempDatas.get(j + "_" + n).toString().trim();
				bb = tempDatas.get(j + 1 + "_" + n).toString().trim();
				if (!aa.equals(bb) || aa.equals("")) {
					base[dd] = j + 1;
					dd++;
				}
			}
			v=dd;
		}
		// 查看每列
		for (int i = col - 1; i >= 0; i--) {
			String a = "";
			String b = "";
			int[] t = new int[50];
			t[0] = 0;
			int d = 1;
			for (int j = 0; j + 1 < row; j++) {
				a = tempDatas.get(j + "_" + i).toString().trim();
				b = tempDatas.get(j + 1 + "_" + i).toString().trim();
				if (!a.equals(b) || a.equals("")) {
					t[d] = j + 1;
					d++;
				}
			}
			t[d] = row;
			//根据第一列合并其他列内容
			if(node.hasAttribute("base")){
				int[] value=new int[60];
				int n=v;
				value=base;
				for(int p=0;p<t.length;p++){
					boolean flag=true;
					for(int m=0;m<base.length;m++){
						if(t[p]==base[m]){
							flag=false;
							break;
						}
					}
					if(flag){
						value[n++]=t[p];
					}
				}
				//排序要合并的跨行值
				for(int u=0;u+1<value.length;u++){
					int u1 = value[u];
					int u2 = value[u+1];
					if(u1>u2 && u2!=0){
						value[u]=u2;
						value[u+1]=u1;
					}
				}
				t=value;
			}
			for (int k = 0; k < node.getElementsByTagName("datatemplate").getLength(); k++) {
				Element node_tr = (Element) node.getElementsByTagName("datatemplate").item(k);
				node_tr = (Element)node_tr.getElementsByTagName("template").item(0);
				Node node_td = node_tr.getElementsByTagName("td").item(i);
				Element e = (Element) node_td;
				if(e.hasAttribute("nospan")){
					continue;
				}
				boolean flag=true;
				for(int j=0;j+1<t.length;j++){
					if(k==t[j]){
						e.setAttribute("rowspan", t[j + 1] - t[j] + "");
						flag=false;
						break;
					}
				}
				if(flag){
					node_tr.removeChild(node_td);
				}
				
			}
		}
		System.out.println();
	}

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		super.service(request, response);
		this.request = request;
		String tt = request.getParameter(name.concat(".sort"));
		if (tt != null) {
			String temp = tt.substring(tt.lastIndexOf(".") + 1);
			if (!((sortInterface) this.model).getOrderBy()) {
				((sortInterface) this.model).sort(temp);
				((sortInterface) this.model).setOrderBy();
			} else if (((sortInterface) this.model).getOrderBy()) {
				((sortInterface) this.model).reverseSort(temp);
				((sortInterface) this.model).setOrderBy();
			}
		}
	}

	protected void createTableRows() {
		createTableRows(0, ((HTMLTableModel) model).getRowCount());
	}

	/**
	 * 设置条件
	 */
	public void setCondition(String condition) {
		((HTMLTableModel) this.model).setCondition(condition);
	}

	/**
	 * 处理表尾的查询按钮
	 */
	public void createSearch() {
		// 得到表尾的查询按钮的标签
		Iterator iter = ExtendElement.findElements(element, "search", "search")
				.iterator();
		while (iter.hasNext()) {
			Element search = (Element) iter.next();
			// 设置标签属性
			String oncli = search.getAttribute("onclick").replaceFirst(
					"#compid#", this.getName());
			// 得到onclick的属性
			search.setAttribute("onclick", oncli);
			// 替换onclick的属性
		}
	}

	/**
	 * 
	 * @param tr：行
	 * @param row：行号
	 */
	private void disposeSpecialTd(Element tr, int row) {
		if (!(this.model instanceof DataShowTableModel)) {
			return;
		}
		NodeList tds = tr.getElementsByTagName("td");
		for (int i = 0; i < tds.getLength(); i++) {
			Element td = (Element) tds.item(i);
			String type = td.getAttribute("type");
			if (type == null || type.equals("td")) {
				continue;
			}
			if (model instanceof SpecialCellsModel)
				((SpecialCellsModel) model).disposeSpecialTd(td, row, type);
		}
	}

	/**
	 * 得表头行
	 */
	public Element getHeadElement() {
		return this.tableHeadElement;
	}

}